/**
 * Description:
 * Class Name:BlockingQueueTest2
 * Date:2022/5/8 15:02
 *
 * @author LTisme
 * @version JAVA17
 */
package 疯狂Java讲义.第16章_多线程._16_6_线程间通信._16_6_3_使用阻塞队列BlockingQueue来控制线程通信;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class Producer extends Thread{
    private BlockingQueue<String> blockingQueue;
    public Producer(BlockingQueue<String> bq){
        this.blockingQueue = bq;
    }

    @Override
    public void run() {
        var strArr = new String[] {"Java", "Struts", "Spring"};
        for (int i = 0; i < 999999999; i++) {
            System.out.println(getName() + "_生产者准备生产集合元素！");
            try {
                Thread.sleep(200);
                // 尝试放入元素，如果队列已满，则线程被阻塞
                blockingQueue.put(strArr[i % 3]);
            }
            catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

class Consumer extends Thread{
    private BlockingQueue<String> blockingQueue;
    public Consumer(BlockingQueue<String> bq){
        this.blockingQueue = bq;
    }

    @Override
    public void run() {
        while (true){
            System.out.println(getName() + "_消费者准备消费集合元素！");
            try {
                Thread.sleep(200);
                // 尝试取出元素，如果队列为空则阻塞线程
                blockingQueue.take();
            }
            catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(getName() + "_消费完成：" + blockingQueue);
        }
    }
}

public class BlockingQueueTest2 {
    public static void main(String[] args) {
        // 创建一个容量为1的BlockingQueue
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(1);
        // 启动3个生产者线程
        new Producer(blockingQueue).start();
        new Producer(blockingQueue).start();
        new Producer(blockingQueue).start();
        // 启动一个消费者线程
        new Consumer(blockingQueue).start();
    }
}
